﻿import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import * as actions from './actions'
import '../common/tree.css'
import './Authorizor.css'
import Selectable from '../common/Selectable'
import Expandable from '../common/Expandable'
import Permission from './Permission'
import { EnvContext } from '../common/EnvContext'

/**
 *  for state structure see document "state.vsd"
 */

class Teachers extends Component {
    static propTypes = {
        teachers: PropTypes.arrayOf(PropTypes.shape({
            eno: PropTypes.string,
            name: PropTypes.string,
            selected: PropTypes.bool,
        })),
        currTeacher: PropTypes.object,
        select: PropTypes.func.isRequired
    }
    render() {
        return <div className='teachers-box'>
            {this.props.teachers && this.props.teachers.length > 0 &&
                this.props.teachers.map((t, idx) =>
                    <div className='teacher' key={idx}>
                        <Selectable
                            text={t.name}
                            selected={t === this.props.currTeacher}
                            onSelect={() => this.props.select(t)}
                        />
                    </div>
                )
            }
        </div>
    }
}
class Section extends Component {
    static propTypes = {
        name: PropTypes.string.isRequired,
        teachers: PropTypes.array,
        expanded: PropTypes.bool,
        focused: PropTypes.bool,
        currTeacher: PropTypes.object,

        expand: PropTypes.func.isRequired,
        selectTeacher: PropTypes.func.isRequired,
        checkPerm: PropTypes.func.isRequired,
        submitChanges: PropTypes.func.isRequired,
        cancelChanges: PropTypes.func.isRequired
    }
    render() {
        return <div>
            <Expandable
                text={this.props.name}
                expanded={this.props.expanded}
                onExpand={() => this.props.expand()}
            />
            {this.props.expanded &&
                <div className='indent-children'>
                    <Teachers
                        teachers={this.props.teachers}
                        currTeacher={this.props.currTeacher}
                        select={t => this.props.selectTeacher(t)}
                    />
                </div>
            }
            {this.props.focused && this.props.currTeacher &&
                <Permission
                    teacher={this.props.currTeacher}
                    checkPerm={this.props.checkPerm}
                    submitChanges={this.props.submitChanges}
                    cancelChanges={this.props.cancelChanges}
                />
            }
        </div>
    }
}
class Department extends Component {
    static propTypes = {
        name: PropTypes.string.isRequired,
        teachers: PropTypes.array,
        current: PropTypes.object,
        expanded: PropTypes.bool,
        focused: PropTypes.bool,
        sections: PropTypes.array,
        
        expand: PropTypes.func.isRequired,
        selectTeacher: PropTypes.func.isRequired,
        checkPerm: PropTypes.func.isRequired,
        submitChanges: PropTypes.func.isRequired,
        cancelChanges: PropTypes.func.isRequired
    }
    render() {
        return (
            <div>
                <Expandable
                    text={this.props.name}
                    expanded={this.props.expanded}
                    onExpand={() => this.props.expand()}
                />
                {this.props.expanded === true &&
                    <div className='indent-children'>
                        <Teachers
                            teachers={this.props.teachers}
                            currTeacher={this.props.current && this.props.current.teacher}
                            select={t => this.props.selectTeacher(null, t)}
                        />
                        {this.props.focused && !this.props.current.section && this.props.current.teacher &&
                        <Permission
                                teacher={this.props.current.teacher}
                                checkPerm={this.props.checkPerm}
                                submitChanges={this.props.submitChanges}
                                cancelChanges={this.props.cancelChanges}
                            />
                        }
                        {this.props.sections && this.props.sections.map(sec =>
                            <Section
                                key={sec.dno}
                                name={sec.name}
                                teachers={sec.teachers}
                                expanded={sec.expanded}
                                focused={this.props.focused && this.props.current.section === sec}
                                currTeacher={this.props.current && this.props.current.teacher}

                                expand={() => this.props.expand(sec)}
                                selectTeacher={t => this.props.selectTeacher(sec, t)}
                                checkPerm={this.props.checkPerm}
                                submitChanges={this.props.submitChanges}
                                cancelChanges={this.props.cancelChanges}
                            />)
                        }
                    </div>
                }
            </div>)
    }
}
class College extends Component {
    static propTypes = {
        teachers: PropTypes.array,
        current: PropTypes.object,
        expanded: PropTypes.bool,
        departments: PropTypes.array.isRequired,

        expand: PropTypes.func.isRequired,
        selectTeacher: PropTypes.func.isRequired,
        checkPerm: PropTypes.func.isRequired,
        submitChanges: PropTypes.func.isRequired,
        cancelChanges: PropTypes.func.isRequired
    }
    render() {
        return (
            <div className='college-root'>
                <EnvContext.Consumer>
                    {({ collegeName }) => (
                        <Expandable
                            text={collegeName}
                            expanded={this.props.expanded}
                            onExpand={() => this.props.expand()}// call expand(dep:undefined,sec:undefined)
                        />)
                    }
                </EnvContext.Consumer>
                <div className='college-children'>
                    {this.props.expanded &&
                        <div className='indent-children'>
                            {this.props.departments.map(d =>
                                <Department
                                    key={d.dno}
                                    name={d.name}
                                    teachers={d.teachers}
                                    current={this.props.current}
                                    expanded={d.expanded}
                                    focused={this.props.current && this.props.current.department === d}
                                    sections={d.sections}

                                    expand={s => this.props.expand(d, s)}
                                    selectTeacher={(sec, t) => this.props.selectTeacher(d, sec, t)}
                                    checkPerm={this.props.checkPerm}
                                    submitChanges={this.props.submitChanges}
                                    cancelChanges={this.props.cancelChanges}
                                />)
                            }
                        </div>
                    }
                </div>
            </div>
        )
    }
}
class Authorizor extends Component {
    static propTypes = {
        college: PropTypes.object,
        current: PropTypes.object,

        expand: PropTypes.func.isRequired,
        selectTeacher: PropTypes.func.isRequired,
        checkPerm: PropTypes.func.isRequired,
        submitChanges: PropTypes.func.isRequired,
        cancelChanges: PropTypes.func.isRequired
    }
    render() {
        return (
            <div className='auth-root'>
                <div className='auth-header'>
                    教师权限管理
                </div>
                <div className='auth-main'>
                    {this.props.college &&
                        <College
                            teachers={this.props.college.teachers}
                            current={this.props.current}
                            expanded={this.props.college.expanded}
                            departments={this.props.college.departments}

                            expand={this.props.expand}
                            selectTeacher={this.props.selectTeacher}
                            checkPerm={idx => this.props.current && this.props.checkPerm(this.props.current.department, this.props.current.section, this.props.current.teacher, idx)}
                            submitChanges={() => this.props.submitChanges(this.props.current)}
                            cancelChanges={() => this.props.cancelChanges(this.props.current)}
                        />
                    }
                </div>
            </div>
        )
    }
}

const mapState2Props = state => {
    var { college, current = null } = state.authorize;
    return { college, current }
};
const mapDispatch2Props = dispatch => ({
    expand: (dep, sec) => dispatch(actions.expand(dep, sec)),
    selectTeacher: (dep, sec, t) => dispatch(actions.selectTeacher(dep, sec, t)),
    checkPerm: (dep, sec, t, idx) => dispatch(actions.checkPerm(dep, sec, t, idx)),
    submitChanges: (dep, sec, t) => dispatch(actions.submitChanges(dep, sec, t)),
    cancelChanges: (dep, sec, t) => dispatch(actions.cancelChanges(dep, sec, t))
});
export default connect(mapState2Props, mapDispatch2Props)(Authorizor);